<!-- 
  dialog 组件的一些细节：

    1. dialog 的默认插槽内容会在第一次 dialog 渲染出来的才创建，关闭时不会销毁它。
        PS: 可以给 dialog 设置一个 destroy-on-close 来控制默认插槽内容的销毁

  form 组件的重置方法 resetFields 为何不生效 

    resetFields 会使用form组件初始化时 model 数据去重置。
 -->

<template>
  <el-space v-loading="loading" class="page" direction="vertical">
    <div class="page__header">
      <el-space>
        <el-button type="default" @click="refresh">刷新</el-button>
        <el-button
          v-has="['base:sys:role:add', 'base:sys:menu:list']"
          type="primary"
          @click="handleAdd"
        >
          新增
        </el-button>
        <el-button
          type="danger"
          :disabled="selectedIds.length <= 0"
          @click="handleDelete(selectedIds)"
        >
          删除
        </el-button>
      </el-space>

      <el-space>
        <el-input v-model="keyWord" clearable placeholder="搜索关键字" />
        <el-button type="primary" @click="handleSearch">搜索</el-button>
      </el-space>
    </div>

    <div class="page__body">
      <el-table
        :data="rows"
        :default-sort="{ prop: query.order, order: query.sort + 'ending' }"
        border
        @sort-change="sortChange"
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="55" />
        <el-table-column label="名称" prop="name" />
        <el-table-column label="标识" prop="label">
          <template #default="{ row }">
            <el-tag>{{ row.label }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="备注" prop="remark" />
        <el-table-column label="创建时间" prop="createTime" sortable="custom" />
        <el-table-column label="更新时间" prop="updateTime" sortable="custom" />
        <el-table-column label="操作">
          <template #default="{ row }">
            <el-space>
              <el-button
                v-has="['base:sys:role:update', 'base:sys:menu:list']"
                type="default"
                text
                bg
                @click="handleEdit(row)"
              >
                编辑
              </el-button>
              <el-button type="danger" text bg @click="handleDelete([row.id])">
                删除
              </el-button>
            </el-space>
          </template>
        </el-table-column>
      </el-table>
    </div>

    <div class="page__footer" style="display: flex; justify-content: flex-end">
      <el-pagination
        background
        layout="total, sizes, prev, pager, next, jumper"
        :default-current-page="query.page"
        :default-page-size="query.size"
        :page-sizes="[5, 10]"
        :total="total"
        @change="handlePaginationChange"
      />
    </div>
  </el-space>

  <el-dialog v-model="visible" :title="title" width="800">
    <el-form ref="formRef" :model="model" :rules="rules" label-width="100">
      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item label="名称" prop="name">
            <el-input v-model="model.name" placeholder="请输入名称" />
          </el-form-item>
        </el-col>

        <el-col :span="12">
          <el-form-item label="标识" prop="label">
            <el-input v-model="model.label" placeholder="请输入标识" />
          </el-form-item>
        </el-col>
      </el-row>

      <el-form-item label="备注" prop="remark">
        <el-input
          v-model="model.remark"
          type="textarea"
          placeholder="请输入备注"
          rows="4"
        />
      </el-form-item>

      <el-form-item label="功能权限" prop="menuIdList">
        <MenuCheck v-model="model.menuIdList" />
      </el-form-item>
    </el-form>

    <template #footer>
      <el-space>
        <el-button type="default" @click="handleCancel">取消</el-button>
        <el-button
          type="success"
          :loading="confirmLoading"
          @click="handleConfirm"
        >
          保存
        </el-button>
      </el-space>
    </template>
  </el-dialog>
</template>

<script>
import {
  getSysRolePage,
  addSysRole,
  updateSysRole,
  deleteSysRole,
} from "@/api/sys";
import MenuCheck from "@/components/menu-check/index.vue";
import { ElMessage, ElMessageBox } from "element-plus";

export default {
  name: "SysRole",

  components: {
    MenuCheck,
  },

  data() {
    return {
      title: "新增",
      visible: false, // dialog 显示条件
      confirmLoading: false, // 保存loading
      selectedIds: [], // 勾选的数据id集合
      loading: false, // 请求中

      keyWord: "", // 搜索关键字
      query: {
        page: 1, // 页码
        size: 5, // 每页条数
        sort: "desc", // 排序方式  升序 asc 降序 desc
        order: "createTime", // 排序字段
      },
      total: 1, // 数据总条数
      rows: [],

      // 表单数据对象
      model: {
        id: undefined,
        name: "",
        label: "",
        remark: "",
        menuIdList: [],
        relevance: 0,
        departmentIdList: [],
      },
      // 表单校验对象
      rules: {
        name: [{ required: true, message: "请输入" }],
        label: [{ required: true, message: "请输入" }],
      },
    };
  },

  // watch: {
  //   query: {
  //     handler() {
  //       this.refresh();
  //     },

  //     deep: true,
  //   },
  // },

  methods: {
    async refresh() {
      try {
        this.loading = true;
        const { list, pagination } = await getSysRolePage({
          ...this.query,
          keyWord: this.keyWord,
        });

        this.rows = list;
        this.total = pagination.total;
      } finally {
        this.loading = false;
      }
    },

    // 分页 current-page 与 page-size 变化时触发
    handlePaginationChange(currentPage, pageSize) {
      console.log("handlePaginationChange", currentPage, pageSize);
      this.query.page = currentPage;
      this.query.size = pageSize;
      this.refresh();
    },

    // 搜索按钮点击
    handleSearch() {
      this.query.page = 1;
      this.refresh();
    },

    // 排序事件
    sortChange({ order, prop }) {
      console.log("order", order, "prop", prop);
      // order - 排序方式 ascending descending null
      // prop  - 排序字段
      this.query.sort = order ? order.replace("ending", "") : "";
      this.query.order = prop;

      this.refresh();
    },

    handleSelectionChange(arr) {
      console.log("handleSelectionChange", arr);

      this.selectedIds = arr.map((item) => item.id);
    },

    // 新增按钮
    handleAdd() {
      this.title = "新增";
      this.visible = true;

      this.$nextTick(() => {
        // 表单重置
        this.model.id = undefined;
        this.$refs.formRef.resetFields();
      });
    },

    // 编辑按钮
    handleEdit(row) {
      this.title = "编辑";
      // 先让dialog与内部的form先使用初始数据做渲染
      this.visible = true;

      this.$nextTick(() => {
        // 数据回填
        // this.model.id = row.id;
        // this.model.name = row.name;
        // this.model.label = row.label;
        // this.model.remark = row.remark;
        // this.model.menuIdList = row.menuIdList;

        // 上面代码，如果有100个字段需要回填，如何办
        // Object.assign(this.model, row);  row里面会有一些无用的属性也写入到 model
        // console.log(this.model, "===");

        // const keys = ["id", "name", "label", "remark", "menuIdList"];
        const keys = Object.keys(this.model);
        const result = keys.reduce((result, key) => {
          result[key] = row[key];
          return result;
        }, {});

        Object.assign(this.model, result);
      });
    },

    // 删除按钮
    async handleDelete(ids) {
      try {
        // 二次确认
        await ElMessageBox.confirm(
          "此操作将永久删除选中数据，是否继续？",
          "提示",
          { type: "warning" },
        );
        // 调用接口
        await deleteSysRole({ ids });

        // 删除表格数据
        this.refresh();
      } catch (error) {
        console.log("error", error);
      }
    },

    /**
     * 取消按钮
     */
    handleCancel() {
      this.$refs.formRef.resetFields();
    },

    /**
     * 保存按钮
     */
    async handleConfirm() {
      try {
        // 表单校验
        await this.$refs.formRef.validate();

        this.confirmLoading = true;
        // 调用接口
        if (this.model.id) {
          // 更新
          await updateSysRole(this.model);
        } else {
          // 新增
          await addSysRole(this.model);
        }

        // 成功
        ElMessage.success("Success");
        // 关闭弹窗
        this.visible = false;
        // 重新刷新表格数据
        this.refresh();
      } catch (error) {
        console.error(error);
      } finally {
        this.confirmLoading = false;
      }
    },
  },

  created() {
    this.refresh();
  },
};
</script>

<style>
.page__header {
  display: flex;
  justify-content: space-between;
}
</style>
